package com.tangyh.basic.sign.comm;

import com.tangyh.basic.sign.exception.DefineException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import org.springframework.web.multipart.MultipartFile;


/**
 * @description 文件辅助类
 * @author 宫清
 * @date 2019年7月9日 下午4:54:07
 * @since JDK1.7
 */
public class FileHelper {

	// ------------------------------公有方法start--------------------------------------------

	/**
	 * 不允许外部创建实例
	 */
	private FileHelper() {
	}

	/**
	 * @description 获取文件字节流
	 * @param filePath {@link String} 文件地址
	 * @return
	 * @throws DefineException
	 * @date 2019年7月10日 上午9:17:00
	 * @author 宫清
	 */
	public static byte[] getBytes(String filePath) throws DefineException {
		File file = new File(filePath);
		FileInputStream fis = null;
		byte[] buffer = null;
		try {
			fis = new FileInputStream(file);
			buffer = new byte[(int) file.length()];
			fis.read(buffer);
		} catch (Exception e) {
			DefineException ex = new DefineException("获取文件字节流失败", e);
			ex.initCause(e);
			throw ex;
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					DefineException ex = new DefineException("关闭文件字节流失败", e);
					ex.initCause(e);
					throw ex;
				}
			}
		}
		return buffer;
	}


	/**
	 * @description 计算文件contentMd5值
	 *
	 * @param filePath {@link String} 文件路径
	 * @return
	 * @author 宫清
	 * @throws DefineException
	 * @date 2019年7月14日 下午1:35:41
	 */
	public static String getContentMD5(String filePath) throws DefineException {
//		BASE64Encoder encoder = new BASE64Encoder();
//		return encoder.encode(getFileMd5Bytes128(filePath));
		return encryptBASE64(getFileMd5Bytes128(filePath));
	}

	public static String getContentMD5(MultipartFile multipartFile) throws DefineException {
//		BASE64Encoder encoder = new BASE64Encoder();
//		return encoder.encode(getFileMd5Bytes128(filePath));
		return encryptBASE64(getFileMd5Bytes128(multipartFile));
	}

	
	/**
	 * @description 根据文件路径，获取文件base64
	 *
	 * @param path
	 * @return	
	 * @throws DefineException
	 * @author 宫清
	 * @date 2019年7月21日 下午4:22:08
	 */
	public static String getBase64Str(String path) throws DefineException {
		InputStream is = null;
		try {
			is = new FileInputStream(new File(path));
			byte[] bytes = new byte[is.available()];
			is.read(bytes);
			return encryptBASE64(bytes);
		} catch (Exception e) {
			DefineException ex = new DefineException("获取文件输入流失败", e);
			ex.initCause(e);
			throw ex;
		}finally {
			if(is != null) {
				try {
					is.close();
				} catch (IOException e) {
					DefineException ex = new DefineException("关闭文件输入流失败", e);
					ex.initCause(e);
					throw ex;
				}
			}
		}
	}
	
	/**
	 * @description 获取文件名称
	 *
	 * @param path 文件路径
	 * @return
	 * @author 宫清
	 * @date 2019年7月21日 下午8:21:16
	 */
	public static String getFileName(String path){
		return new File(path).getName();
	}
	// ------------------------------公有方法end----------------------------------------------

	// ------------------------------私有方法start--------------------------------------------

	/**
	 * @description 获取文件Md5二进制数组（128位）
	 *
	 * @param filePath {@link String} 文件路径
	 * @return
	 * @author 宫清
	 * @throws DefineException
	 * @date 2019年7月14日 下午1:36:42
	 */
	private static byte[] getFileMd5Bytes128(String filePath) throws DefineException {
		FileInputStream fis = null;
		try {
			fis = new FileInputStream(new File(filePath));
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] buffer = new byte[fis.available()];
			int len = -1;
			while ((len = fis.read(buffer, 0, 1024)) != -1) {
				md5.update(buffer, 0, len);
			}
			return md5.digest();
		} catch (Exception e) {
			DefineException ex = new DefineException("获取文件md5二进制数组失败", e);
			ex.initCause(e);
			throw ex;
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					DefineException ex = new DefineException("关闭读写流失败", e);
					ex.initCause(e);
					throw ex;
				}
			}
		}
	}

	private static byte[] getFileMd5Bytes128(MultipartFile multipartFile) throws DefineException {
		InputStream fis = null;
		try {
			fis = multipartFile.getInputStream();
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] buffer = new byte[fis.available()];
			int len = -1;
			while ((len = fis.read(buffer, 0, 1024)) != -1) {
				md5.update(buffer, 0, len);
			}
			return md5.digest();
		} catch (Exception e) {
			DefineException ex = new DefineException("获取文件md5二进制数组失败", e);
			ex.initCause(e);
			throw ex;
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					DefineException ex = new DefineException("关闭读写流失败", e);
					ex.initCause(e);
					throw ex;
				}
			}
		}
	}
	
	public static void main(String[] args) {
//		try {
//			String s  = "d:/AAAAA.pdf";
//			System.out.println(getContentMD5(s));
//		} catch (DefineException e) {
//			e.printStackTrace();
//		}
		String a="D:\\data\\projects\\uploadfile\\file\\1467690146651439104\\模板名称.pdf";
		try {
			System.out.println(getBytes(a));
		} catch (DefineException e) {
			e.printStackTrace();
		}
	}
	// ------------------------------私有方法end----------------------------------------------




	/**
	 * BASE64Encoder 加密
	 * @param data
	 *            要加密的数据
	 * @return 加密后的字符串
	 */
	public static String encryptBASE64(byte[] data) {
		// BASE64Encoder encoder = new BASE64Encoder();
		// String encode = encoder.encode(data);
		// 从JKD 9开始rt.jar包已废除，从JDK 1.8开始使用java.util.Base64.Encoder
		Encoder encoder = Base64.getEncoder();
		String encode = encoder.encodeToString(data);
		return encode;
	}
	/**
	 * BASE64Decoder 解密
	 * @param data
	 *            要解密的字符串
	 * @return 解密后的byte[]
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String data) throws Exception {
		// BASE64Decoder decoder = new BASE64Decoder();
		// byte[] buffer = decoder.decodeBuffer(data);
		// 从JKD 9开始rt.jar包已废除，从JDK 1.8开始使用java.util.Base64.Decoder
		Decoder decoder = Base64.getDecoder();
		byte[] buffer = decoder.decode(data);
		return buffer;
	}


//	public static String getMd5(MultipartFile file) throws Exception{
//			byte[] uploadBytes = file.getBytes();
//			MessageDigest md5 = MessageDigest.getInstance("MD5");
//			byte[] digest = md5.digest(uploadBytes);
//			String hashString = new BigInteger(1, digest).toString(16);
//			return hashString;
//	}

}
